home *** CD-ROM | disk | FTP | other *** search
- #define DEBUG 1
- /*
- * oopsDebug.c
- * This is a modified version of the Think C oops (object support)
- * module that executes a Debug trap if you try to dispatch on a
- * NULL instance variable. It should only be used if you are running
- * under the Think C debugger or have a hardware debugger (MacsBug
- * or TMON) installed. It would be useful to extend this so it
- * printed the calling chain when the trap occurs -- this would
- * permit capturing debug information even in production software.
- *
- * If you continue after the debug trap occurs, the function will
- * return to its caller. This is only to allow you to evaluate
- * variables in the caller's context -- you shouldn't assume
- * that the program may continue without further failure.
- *
- * Symantec does not endorse or support these changes to oops.c.
- * The object dispatch mechanism is not documented. It can and
- * will change in future versions of Think C.
- *
- * This change to oops.c will not work with future versions of Think C.
- *
- * The modifications are copyright 1991 Martin Minow. They may
- * be used and distributed by any individual or organization
- * under terms of their license with Symantec Corporation.
- */
- /*
- * oops.c
- *
- * Copyright (c) 1989 Symantec Corporation. All rights reserved.
- *
- */
- #include "oops.h"
-
- #ifndef DEBUG
- #define DEBUG 0
- #endif
-
- #ifdef DIRECT
- #define member memberD
- #define bless blessD
- #define __msg __msgD
- #else
- #define INDIRECT
- #endif
-
- void __msg(void);
-
-
- /*
- * new - allocate a new object
- *
- * The new object is returned. (This implementation initializes the
- * object to all-bits-zero, but it may be unwise to rely on this.)
- *
- * This routine is for use with indirect classes. There is no
- * corresponding facility for direct classes.
- *
- * If an object is created other than by calling this routine, it
- * must be marked as belonging to its class by calling "bless" or
- * "blessD". (Since allocation of direct objects is the programmer's
- * responsibility, "blessD" must always be called.)
- *
- */
-
- #ifdef INDIRECT
- void *
- new(class)
- void *class;
- {
- asm {
- moveq #0,d0
- movea.l class,a1
- move.w (a1),d0 ; D0.L = class size
- _NewHandle CLEAR
- move.l a0,d0
- beq.s @1
- suba.l a5,a1 ; A1.W = class ID
- movea.l (a0),a0 ; <<indirect>>
- move.w a1,(a0)
- @1 }
- }
- #endif INDIRECT
-
-
- /*
- * delete - free an object
- *
- * This routine is for use with indirect classes. There is no
- * corresponding facility for direct classes.
- *
- */
-
- #ifdef INDIRECT
- void
- delete(obj)
- void *obj;
- {
- asm {
- move.l obj,d0
- beq.s @1
- movea.l d0,a0
- _DisposHandle
- @1 }
- }
- #endif INDIRECT
-
-
- /*
- * member, memberD - test whether an object is a member of a class
- *
- * A non-zero value is returned if the object's class, or any of its
- * ancestors, is equal to the given class.
- *
- * "member" is for use only with indirect classes, and "memberD" is
- * for use only with direct classes. Do not attempt to use either
- * function to test whether a direct object is a member of an indirect
- * class, or whether an indirect object is a member of a direct class.
- * (Of course, in these cases, the answer is "no"!)
- *
- */
- #if DEBUG
- static char DebugMember[] = "\pNULL Member";
- #endif
-
- int
- member(obj, class)
- void *obj, *class;
- {
- asm {
- move.l class,d1
- sub.l a5,d1 ; D1.W = target class ID
- movea.l obj,a1
- #if DEBUG
- move.l a1,d0 ; Copy to set condition codes
- bne.s @3 ; Ok
- pea DebugMember
- DebugStr
- bra.s @2 ; Return to the scene of the crime
- @3
- #endif
- #ifdef INDIRECT
- movea.l (a1),a1 ; <<indirect>>
- #endif INDIRECT
- move.w (a1),d0 ; D0.W = class ID
- @1 cmp.w d0,d1
- beq.s @2
- lea 2(a5,d0.w),a1 ; A1 ==> class record + 2
- move.w (a1)+,d0 ; D0.W = #methods - 1
- add.w d0,d0
- add.w d0,d0
- move.w 4(a1,d0.w),d0 ; D0.W = superclass ID
- bne.s @1
- @2 }
- }
-
-
- /*
- * bless, blessD - mark an object as being of a particular class
- *
- * If an object is created other than by "new", this routine must
- * be called to mark it as a member of its class.
- *
- * Do not use this routine to change an object's class!
- *
- */
-
- void
- bless(obj, class)
- void *obj, *class;
- {
- asm {
- move.l class,d1
- sub.l a5,d1 ; D1.W = class ID
- movea.l obj,a1
- #ifdef INDIRECT
- movea.l (a1),a1 ; <<indirect>>
- #endif INDIRECT
- move.w d1,(a1)
- }
- }
-
-
- /*
- * __msg, __msgD - message dispatcher
- *
- * The dispatcher is called only from code generated by the compiler.
- *
- */
- #if DEBUG
- static char DebugMsg[] = "\pNULL Method";
- #endif
-
- void
- __msg()
- {
- asm {
- movea.l 4(sp),a1
- move.w -(a1),d2 ; D2.W = message ID
- movea.l 8(sp),a1
- #if DEBUG
- move.l a1,d0 ; Copy to set condition codes
- bne.s @3 ; Ok
- pea DebugMsg
- DebugStr ; Oops
- bra.s @4 ; Return to the scene of the crime
- @3
- #endif
- #ifdef INDIRECT
- movea.l (a1),a1 ; <<indirect>>
- #endif INDIRECT
- @1 move.w (a1),d0
- lea 2(a5,d0.w),a1 ; A1 ==> class record + 2
- move.w (a1)+,d0 ; D0.W = #methods - 1
- @2 move.w (a1)+,d1 ; D1.W = method ID
- cmp.w (a1)+,d2
- dbeq d0,@2
- bne.s @1 ; not found - search superclass
- lea 0(a5,d1.w),a0 ; A0 ==> method
- @4 }
- }
-